package com.ruibang.glass.common.utils;

import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class Rsa2Utils {


    private static final String ALGORITHM = "RSA";
    private static final String ALGORITHMS_SHA1WithRSA = "SHA1WithRSA";
    private static final String ALGORITHMS_SHA256WithRSA = "SHA256WithRSA";
    private static final String DEFAULT_CHARSET = "UTF-8";

    private static String getAlgorithms(boolean isRsa2) {
        return isRsa2 ? ALGORITHMS_SHA256WithRSA : ALGORITHMS_SHA1WithRSA;
    }

    /**
     * 生成秘钥对
     * @return
     * @throws NoSuchAlgorithmException
     */
  /*  public static RsaKeyPair generaterKeyPair() throws NoSuchAlgorithmException{
        KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM);
        SecureRandom random = new SecureRandom();
        //            SecureRandom random = new SecureRandom(seedStr.getBytes()); // 随机因子一样，生成出来的秘钥会一样
        // 512位已被破解，用1024位,最好用2048位
        keygen.initialize(2048, random);
        // 生成密钥对
        KeyPair keyPair = keygen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
        RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
        String privateKeyStr = Base64.getEncoder().encodeToString(privateKey.getEncoded());
        String publicKeyStr = Base64.getEncoder().encodeToString(publicKey.getEncoded());
        return new RsaKeyPair(publicKeyStr,privateKeyStr);
    }*/


    /**
     * 对称加密算法
     *
     * @author zhouzhian
     */
    public static class AesUtil {
        private static final String ALGORITHM = "AES";
        private static final String DEFAULT_CHARSET = "UTF-8";

        /**
         * 生成秘钥
         *
         * @return
         * @throws NoSuchAlgorithmException
         */
        public static String generaterKey() throws NoSuchAlgorithmException {
            KeyGenerator keygen = KeyGenerator.getInstance(ALGORITHM);
            keygen.init(128, new SecureRandom()); // 16 字节 == 128 bit
            //            keygen.init(128, new SecureRandom(seedStr.getBytes())); // 随机因子一样，生成出来的秘钥会一样
            SecretKey secretKey = keygen.generateKey();
            return Base64.getEncoder().encodeToString(secretKey.getEncoded());
        }

        /**
         *
         */
        public static SecretKeySpec getSecretKeySpec(String secretKeyStr) {
            byte[] secretKey = Base64.getDecoder().decode(secretKeyStr);
            System.out.println(secretKey.length);
            return new SecretKeySpec(secretKey, ALGORITHM);
        }

        /**
         * 加密
         */
        public static String encrypt(String content, String secretKey) throws Exception {
            Key key = getSecretKeySpec(secretKey);
            Cipher cipher = Cipher.getInstance(ALGORITHM);// 创建密码器
            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(content.getBytes(DEFAULT_CHARSET));
            return Base64.getEncoder().encodeToString(result);
        }

        /**
         * 解密
         */
        public static String decrypt(String content, String secretKey) throws Exception {
            Key key = getSecretKeySpec(secretKey);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
            return new String(result);
        }
    }


    /**
     * 获取公钥
     *
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static RSAPublicKey getPublicKey(String publicKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(publicKey);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return (RSAPublicKey) keyFactory.generatePublic(spec);
    }

    /**
     * 获取私钥
     *
     * @param privateKey
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws Exception
     */
    public static RSAPrivateKey getPrivateKey(String privateKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(privateKey);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return (RSAPrivateKey) keyFactory.generatePrivate(spec);
    }

    /**
     * 要私钥签名
     *
     * @throws InvalidKeySpecException
     * @throws Exception
     */
    public static String sign(String content, String privateKey, boolean isRsa2) throws Exception {
        PrivateKey priKey = getPrivateKey(privateKey);
        java.security.Signature signature = java.security.Signature.getInstance(getAlgorithms(isRsa2));
        signature.initSign(priKey);
        signature.update(content.getBytes(DEFAULT_CHARSET));
        byte[] signed = signature.sign();
        return Base64.getEncoder().encodeToString(signed);
    }

    /**
     * 要公钥签名
     */
    public static boolean verify(String content, String sign, String publicKey, boolean isRsa2) throws Exception {
        PublicKey pubKey = getPublicKey(publicKey);
        java.security.Signature signature = java.security.Signature.getInstance(getAlgorithms(isRsa2));
        signature.initVerify(pubKey);
        signature.update(content.getBytes(DEFAULT_CHARSET));
        return signature.verify(Base64.getDecoder().decode(sign));
    }


    /**
     * 加密
     *
     * @param content    加密内容
     * @param privateKey 私钥
     * @return
     */
    public static String encrypt(String content, Key privateKey) throws Exception {
        Cipher cipher = null;
        //Key privateKey = getPrivateKey(privateKeyStr);
        cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(content.getBytes(DEFAULT_CHARSET));
        return Base64.getEncoder().encodeToString(result);
    }


    /**
     * 加密
     *
     * @param content       加密内容
     * @param privateKeyStr 私钥
     * @return
     */
    public static String encrypt(String content, String privateKeyStr) throws Exception {
        Cipher cipher = null;
        //Key privateKey = getPrivateKey(privateKeyStr);
        cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(privateKeyStr));
        byte[] result = cipher.doFinal(content.getBytes(DEFAULT_CHARSET));
        return Base64.getEncoder().encodeToString(result);
    }


    /**
     * 解密
     *
     * @param content   加密内容
     * @param publicKey 公钥
     * @return
     */
    public static String decrypt(String content, Key publicKey) throws Exception {
        Cipher cipher = null;
        cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
        return new String(result);
    }


    /**
     * VNC 统一生成 token
     *
     * @param ip
     * @return
     */
    public static String vncTokenGen(String ip) {
        String salt = DigestUtils.md5Hex("appcloud-common");
//        String ymd = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String encodeStr = DigestUtils.md5Hex(salt.concat(ip));
        return encodeStr;
    }

    /**
     * 解密
     *
     * @param content   加密内容
     * @param publicKey 公钥
     * @return
     */
    public static String decrypt(String content, String publicKey) throws Exception {
        Cipher cipher = null;
        cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, getPublicKey(publicKey));
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
        return new String(result);
    }


  /* public static void main(String[] args) throws Exception{

       String privateKeyStr =  "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZ5LFOkg6IhmGoX8IbTGz+xQjI1QzhMFA3RAO/yQp5xEcTS/H5IytaDMQ4uQnHxdDnjeIWcgmsvxRCivg9DxO3ObnoEJP3vNN+X/c3vzggd5ngjmcjWkHafODOlZNk/2uvHLnYuYI5+OvPAr6CaN48ujrtt4uuC/XmaXNZDJP94Lmr3CSZOGq3+Rx80MFWpPW2RZjB3PjtXSA47HB8oqko4sd5Da9AXq9llS3uW2mGGEi4IB4ZWo3iALDnkYLSL4jRYZjLt2rqFSaPzYKCmCGPyzrOh4mgV5IHYu8yS7n6IQUpB9ujqwUNjA3Vd9MEVRCtCysq9UBeW5MeGlxgdVSXAgMBAAECggEAZCSsuNtUt8Ty0dWWg5slJljjkYUKf5On737EDc5ukbSHJ+h4ys33DP9XxS2sTqLMgZITuNV2tEIXlgHG7jzccJQRBRGcqE7pNciPIGi/xmjt6nHgbeHzDpHK3MP7CXMpCOfhjEWTl9QC50/61vQVAmGRrVWOgLDp0Il4dU85ErBhdCEZP2uoCQBCv3UNChXq5TNoj17pkeega7vUQUNtYT4APW83x2qVfhqjYYNs19TZc4Itd8QQnF92+gHBFwCL5ZsoIFzV9QCuMhWULbrrN32HONCvAhnKONbysoThcffZZoSMui6cQj/jYPP8pcsUIFJqTbMzn06ZcnQUsf6ywQKBgQDc5vquUd+/Il2NrXWmQWu+4EWfylOI6YVGgdIaj1OG+0xQ5741vT8vVvm1O0DhpqtSzIyoGjSWmdd1hXIIENDvwq12kUKt2fmnRkj0TIExgZI2nhhbcYvFDH7mnBuJcpG/Cq7/ydngl6njb+CD1l7pbVDixeSwhly9DoNUVKY6dwKBgQCyWC3mJKUbU/WpMBXu1GZd/DrNE3cD8sOc+Jj54UgO8ntyo6JXcVQjl6G2IYswRE9acL5ebJTgdnW/RGq5PuCniQJ7wamdb3CE60/NNufHwavEWQN5S/VwoTPQJuAebp3MYt//Y4rcAH4SW1FwghqdVsZpHwV5DFUOLjHlWw4e4QKBgBf2QjkIjpHII4fLyhhHvm1NHKBRrTALzLYyPN0+sNvShJu+F6byqVj0QVAEZmxTzP/FSnitpwizFWkdGZqAYHmxj2luJmJ/Y5JekGlXpyf8mySrj47TyUqNqXJQerg1IlQrz4HVnnm7WeVe7GbAqTj+76g5uS3g1Ux4t4w9Rm7PAoGBAKXVsPhr4stCixBDkmF+R6HlRJglHWoidxqjXzwb63FasMesuOwuiVp/SPOexVqgallitOIAfX8rJ9ouuD6A5U1j7Vc+gYXPdgVi+dWM1IG+6QWu77f+lb+hZhiLzaL+oOTInBlSanCgVJqlJ1lC4ZSkd+KP4frpKL4C3oqy3LKBAoGANaSaTF5/ux0DYLYgsDctX8J155jWiSG0+vzjGgMBK/2ibf6FJdnoZJEDbVtYfblGQ55pdfRbJCuvQo2qmxw+mZ6UrtbCqhaSn8dlUileVzq4yCwEvSRQKUdM50+lXVfZ9P2yrhlmXcAfY6cLl9+h80nJ+9tEl3vtEYQyASZtO0Q=" ;//mRsaKeyPair.getPrivateKey();
       String publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmeSxTpIOiIZhqF/CG0xs/sUIyNUM4TBQN0QDv8kKecRHE0vx+SMrWgzEOLkJx8XQ543iFnIJrL8UQor4PQ8Ttzm56BCT97zTfl/3N784IHeZ4I5nI1pB2nzgzpWTZP9rrxy52LmCOfjrzwK+gmjePLo67beLrgv15mlzWQyT/eC5q9wkmThqt/kcfNDBVqT1tkWYwdz47V0gOOxwfKKpKOLHeQ2vQF6vZZUt7ltphhhIuCAeGVqN4gCw55GC0i+I0WGYy7dq6hUmj82Cgpghj8s6zoeJoFeSB2LvMku5+iEFKQfbo6sFDYwN1XfTBFUQrQsrKvVAXluTHhpcYHVUlwIDAQAB";//mRsaKeyPair.getPublicKey();
       String content = "{\"startTime\":1540396800000,\"endTime\":1540656000000,\"orgName\":\"提明科技\",\"mechine\":\"BFEBFBFF000806EA|MMG5S000001177BNP009F|\"}";

       *//* String content = "SecurityUtil.RsaUtil.getPrivateKey(privateKeyStr)";
        // 生成秘钥对
        String privateKeyStr =  "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZ5LFOkg6IhmGoX8IbTGz+xQjI1QzhMFA3RAO/yQp5xEcTS/H5IytaDMQ4uQnHxdDnjeIWcgmsvxRCivg9DxO3ObnoEJP3vNN+X/c3vzggd5ngjmcjWkHafODOlZNk/2uvHLnYuYI5+OvPAr6CaN48ujrtt4uuC/XmaXNZDJP94Lmr3CSZOGq3+Rx80MFWpPW2RZjB3PjtXSA47HB8oqko4sd5Da9AXq9llS3uW2mGGEi4IB4ZWo3iALDnkYLSL4jRYZjLt2rqFSaPzYKCmCGPyzrOh4mgV5IHYu8yS7n6IQUpB9ujqwUNjA3Vd9MEVRCtCysq9UBeW5MeGlxgdVSXAgMBAAECggEAZCSsuNtUt8Ty0dWWg5slJljjkYUKf5On737EDc5ukbSHJ+h4ys33DP9XxS2sTqLMgZITuNV2tEIXlgHG7jzccJQRBRGcqE7pNciPIGi/xmjt6nHgbeHzDpHK3MP7CXMpCOfhjEWTl9QC50/61vQVAmGRrVWOgLDp0Il4dU85ErBhdCEZP2uoCQBCv3UNChXq5TNoj17pkeega7vUQUNtYT4APW83x2qVfhqjYYNs19TZc4Itd8QQnF92+gHBFwCL5ZsoIFzV9QCuMhWULbrrN32HONCvAhnKONbysoThcffZZoSMui6cQj/jYPP8pcsUIFJqTbMzn06ZcnQUsf6ywQKBgQDc5vquUd+/Il2NrXWmQWu+4EWfylOI6YVGgdIaj1OG+0xQ5741vT8vVvm1O0DhpqtSzIyoGjSWmdd1hXIIENDvwq12kUKt2fmnRkj0TIExgZI2nhhbcYvFDH7mnBuJcpG/Cq7/ydngl6njb+CD1l7pbVDixeSwhly9DoNUVKY6dwKBgQCyWC3mJKUbU/WpMBXu1GZd/DrNE3cD8sOc+Jj54UgO8ntyo6JXcVQjl6G2IYswRE9acL5ebJTgdnW/RGq5PuCniQJ7wamdb3CE60/NNufHwavEWQN5S/VwoTPQJuAebp3MYt//Y4rcAH4SW1FwghqdVsZpHwV5DFUOLjHlWw4e4QKBgBf2QjkIjpHII4fLyhhHvm1NHKBRrTALzLYyPN0+sNvShJu+F6byqVj0QVAEZmxTzP/FSnitpwizFWkdGZqAYHmxj2luJmJ/Y5JekGlXpyf8mySrj47TyUqNqXJQerg1IlQrz4HVnnm7WeVe7GbAqTj+76g5uS3g1Ux4t4w9Rm7PAoGBAKXVsPhr4stCixBDkmF+R6HlRJglHWoidxqjXzwb63FasMesuOwuiVp/SPOexVqgallitOIAfX8rJ9ouuD6A5U1j7Vc+gYXPdgVi+dWM1IG+6QWu77f+lb+hZhiLzaL+oOTInBlSanCgVJqlJ1lC4ZSkd+KP4frpKL4C3oqy3LKBAoGANaSaTF5/ux0DYLYgsDctX8J155jWiSG0+vzjGgMBK/2ibf6FJdnoZJEDbVtYfblGQ55pdfRbJCuvQo2qmxw+mZ6UrtbCqhaSn8dlUileVzq4yCwEvSRQKUdM50+lXVfZ9P2yrhlmXcAfY6cLl9+h80nJ+9tEl3vtEYQyASZtO0Q=" ;//mRsaKeyPair.getPrivateKey();
        String publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmeSxTpIOiIZhqF/CG0xs/sUIyNUM4TBQN0QDv8kKecRHE0vx+SMrWgzEOLkJx8XQ543iFnIJrL8UQor4PQ8Ttzm56BCT97zTfl/3N784IHeZ4I5nI1pB2nzgzpWTZP9rrxy52LmCOfjrzwK+gmjePLo67beLrgv15mlzWQyT/eC5q9wkmThqt/kcfNDBVqT1tkWYwdz47V0gOOxwfKKpKOLHeQ2vQF6vZZUt7ltphhhIuCAeGVqN4gCw55GC0i+I0WGYy7dq6hUmj82Cgpghj8s6zoeJoFeSB2LvMku5+iEFKQfbo6sFDYwN1XfTBFUQrQsrKvVAXluTHhpcYHVUlwIDAQAB";//mRsaKeyPair.getPublicKey();


        Key privateKey = getPrivateKey(privateKeyStr);
        Key publicKey = getPublicKey(publicKeyStr);

        // 私钥加密、公钥解密
        String encryptStr = encrypt(content, privateKeyStr);
        String decryptStr = decrypt(encryptStr, publicKeyStr);

        encryptStr = Rsa2Utils.encrypt(content, publicKeyStr);
        decryptStr = Rsa2Utils.decrypt(encryptStr, privateKeyStr);

//            Assert.assertEquals(content, decryptStr);
        System.out.println("-----------encryptStr------------------");
        System.out.println(encryptStr);
        System.out.println("-----------decryptStr------------------");
        System.out.println(decryptStr);*//*



      // String content = "testAes";
      *//* String secretKeyStr = Rsa2Utils.AesUtil.generaterKey();
       System.out.println("-----------secretKeyStr------------------");
       System.out.println(secretKeyStr);
       String encryptStr = Rsa2Utils.AesUtil.encrypt(content, secretKeyStr);
       String decryptStr = Rsa2Utils.AesUtil.decrypt(encryptStr, secretKeyStr);
       System.out.println("-----------encryptStr------------------");
       System.out.println(encryptStr);
       System.out.println("-----------decryptStr------------------");
       System.out.println(decryptStr);*//*



       Key privateKey = Rsa2Utils.getPrivateKey(privateKeyStr);
       Key publicKey = Rsa2Utils.getPublicKey(publicKeyStr);

       // 私钥加密、公钥解密
       String encryptStr = Rsa2Utils.encrypt(content, privateKey);
       String decryptStr = Rsa2Utils.decrypt(encryptStr, publicKeyStr);
//            Assert.assertEquals(content, decryptStr);
       System.out.println("-----------encryptStr------------------");
       System.out.println(encryptStr);
       System.out.println("-----------decryptStr------------------");
       System.out.println(decryptStr);

       // 公钥加密、私钥解密
       encryptStr = Rsa2Utils.encrypt(content, privateKey);

       System.out.println(encryptStr);
       decryptStr = Rsa2Utils.decrypt(encryptStr, publicKey);



    }
*/

}